<!-- AdminMap.vue -->
<script setup lang="ts">
import { useInstructionStore } from '@/stores/modules/instruction'
import type { Instruction } from '@/types/AIResponse'
import MapView from '@arcgis/core/views/MapView'
import Graphic from '@arcgis/core/Graphic'
import SketchViewModel from '@arcgis/core/widgets/Sketch/SketchViewModel'
import { markRaw, onMounted, shallowRef, watch, nextTick } from 'vue'
import { ref } from 'vue'
import Handles from '@arcgis/core/core/Handles.js'
import { onBeforeUnmount } from 'vue'
import { useRoute } from 'vue-router'
import * as echarts from 'echarts'
// 导入拆分后的工具函数
import { initMap, showLayer } from '@/utils/mapLayers'
import { executeMapOperation, processInstructionQueue } from '@/utils/mapInstructionHandler'
import { getLabel, initFeatureFormData, submitFeatureForm } from '@/utils/mapFormUtils'

// 格式化距离显示
const formatDistance = (distanceStr: string) => {
  const distance = parseInt(distanceStr.replace('米', ''))
  if (distance < 100) {
    return `${distance}米 (步行约${Math.ceil(distance / 80)}分钟)`
  } else if (distance < 1000) {
    return `${distance}米 (步行约${Math.ceil(distance / 80)}分钟)`
  } else {
    return `${(distance / 1000).toFixed(1)}公里 (步行约${Math.ceil(distance / 80)}分钟)`
  }
}

// 根据POI类型获取标签样式
const getPoiTagType = (poiType: string) => {
  const typeMap: Record<string, string> = {
    '餐饮服务': 'success',
    '中餐厅': 'success',
    '快餐厅': 'success',
    '购物': 'warning',
    '商场': 'warning',
    '超市': 'warning',
    '医疗': 'danger',
    '医院': 'danger',
    '药店': 'danger',
    '交通设施': 'info',
    '公交站': 'info',
    '地铁站': 'info',
    '住宿服务': 'primary',
    '酒店': 'primary',
    '娱乐': ''  // 默认样式
  }

  // 查找匹配的类型
  for (const key in typeMap) {
    if (poiType.includes(key)) {
      return typeMap[key]
    }
  }

  return ''  // 默认样式
}

// 地图容器
const mapViewContainer = ref<HTMLDivElement>()
const dialogVisible = ref(false)
const attributes = ref<{ [key: string]: any }>({})
// 添加要素属性对话框
const featureFormVisible = ref(false)
const featureFormData = ref<{ [key: string]: any }>({})
const featureFormTitle = ref('添加要素属性')
const dialogTitle = ref('要素属性')
const highlightHandle: Handles = new Handles() // 高亮显示句柄
const route = useRoute()
const isViewActive = ref(false)
// 指令处理
const store = useInstructionStore()
// 新增处理状态标识
const isProcessing = ref(false)
// ECharts图表容器
const chartContainer = ref<HTMLDivElement>()
// ECharts实例
let chartInstance: echarts.ECharts | null = null

// 组件卸载时标记为非激活
onBeforeUnmount(() => {
  isViewActive.value = false
  // 销毁ECharts实例
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})

// 初始化或更新ECharts图表
const initOrUpdateChart = async () => {
  if (!attributes.value.chartType || !attributes.value.data) return

  await nextTick()
  if (!chartContainer.value) return

  // 如果已经有实例，先销毁
  if (chartInstance) {
    chartInstance.dispose()
  }

  // 初始化ECharts实例
  chartInstance = echarts.init(chartContainer.value)

  // 根据chartType设置不同的图表配置
  const option: echarts.EChartsOption = {
    title: {
      text: attributes.value.title || '数据报表',
      left: 'center'
    },
    tooltip: {
      trigger: 'item'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      top: 'middle'
    },
    series: []
  }

  // 根据图表类型设置系列数据
  switch (attributes.value.chartType) {
    case 'pie':
      option.series = [{
        name: attributes.value.title,
        type: 'pie',
        radius: '60%',
        center: ['60%', '50%'],
        data: attributes.value.data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }]
      break
    case 'bar':
      option.xAxis = {
        type: 'category',
        data: attributes.value.data.map((item: any) => item.name)
      }
      option.yAxis = {
        type: 'value'
      }
      option.series = [{
        name: attributes.value.title,
        type: 'bar',
        data: attributes.value.data.map((item: any) => item.value)
      }]
      break
    case 'line':
      option.xAxis = {
        type: 'category',
        data: attributes.value.data.map((item: any) => item.name)
      }
      option.yAxis = {
        type: 'value'
      }
      option.series = [{
        name: attributes.value.title,
        type: 'line',
        data: attributes.value.data.map((item: any) => item.value)
      }]
      break
    default:
      // 默认使用饼图
      option.series = [{
        name: attributes.value.title,
        type: 'pie',
        radius: '60%',
        center: ['60%', '50%'],
        data: attributes.value.data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }]
  }

  // 设置图表配置
  chartInstance.setOption(option)
}

// 初始化地图
const map = initMap()

// 初始化MapView
const view = new MapView({
  map: map,
  center: [110.641855, 26.73],
  zoom: 13,
})

onMounted(async () => {
  view.container = mapViewContainer.value!
})

// 添加要素确认对话框
let tempGraphic: Graphic | null = null
const currentInstruction = shallowRef<Instruction>()
let sketchViewModel: SketchViewModel = new SketchViewModel({
  view: view,
  layer: showLayer,
  updateOnGraphicClick: true,
})

// 执行地图操作的包装函数
const executeMapOperationWrapper = async (instruction: Instruction) => {
  await executeMapOperation(
    instruction,
    view,
    sketchViewModel!,
    tempGraphic,
    (graphic) => (tempGraphic = graphic),
    (instruction) => (currentInstruction.value = markRaw(instruction)),
    (layerType, aiAttributes) => {
      featureFormData.value = initFeatureFormData(layerType, aiAttributes)
    },
    (title) => (featureFormTitle.value = title),
    (visible) => (featureFormVisible.value = visible),
    featureFormVisible.value,
    featureFormData.value,
    (data) => (featureFormData.value = data),
    (attrs) => (attributes.value = attrs),
    (title) => (dialogTitle.value = title),
    (visible) => (dialogVisible.value = visible),
    highlightHandle,
  )
}

// 提交要素表单
const handleSubmitFeatureForm = async () => {
  if (!currentInstruction.value) return

  await submitFeatureForm(
    currentInstruction.value.layerType,
    featureFormData.value,
    tempGraphic,
    (visible) => (featureFormVisible.value = visible),
    (instruction) => (currentInstruction.value = instruction),
  )
}

// 监听路由变化
watch(
  () => route.path,
  async (path) => {
    isViewActive.value = path === '/Admin/map'
    console.log('视图激活状态:', isViewActive.value)
    if (isViewActive.value) {
      console.log('视图激活，开始处理队列')
      await processInstructionQueue(
        store.queue,
        isProcessing.value,
        (value) => (isProcessing.value = value),
        isViewActive.value,
        executeMapOperationWrapper,
      )
    }
  },
  { immediate: true },
)

// 监听对话框显示状态
watch(
  () => dialogVisible.value,
  async (visible) => {
    if (visible && attributes.value.chartType) {
      // 当对话框显示且有图表数据时，初始化图表
      await initOrUpdateChart()
    }
  }
)

// 监听属性变化
watch(
  () => attributes.value,
  async () => {
    if (dialogVisible.value && attributes.value.chartType) {
      // 当属性变化且有图表数据时，更新图表
      await initOrUpdateChart()
    }
  },
  { deep: true }
)

</script>

<template>
  <div id="mapViewContainer" ref="mapViewContainer" class="mapView"></div>

  <!-- 属性查看面板 -->
  <el-dialog v-model="dialogVisible" :title="dialogTitle" :modal="false" width="600px">
    <!-- 当数据是报表数据时，使用ECharts展示 -->
    <div v-if="attributes.chartType" ref="chartContainer" style="width: 100%; height: 400px;"></div>
    <!-- 当数据是周边查询结果时，使用卡片式布局展示 -->
    <div v-else-if="attributes.poiList" class="poi-result-container">
      <div class="poi-summary">
        <el-tag type="info">查询中心: {{ attributes.centerLocation }}</el-tag>
        <el-tag type="info">半径: {{ attributes.radius }}米</el-tag>
        <el-tag type="info">设施类型: {{ attributes.facilityType }}</el-tag>
      </div>
      <el-scrollbar height="400px">
        <div class="poi-list">
          <el-card v-for="poi in attributes.poiList" :key="poi.index" class="poi-card" shadow="hover">
            <template #header>
              <div class="poi-card-header">
                <span class="poi-name">{{ poi.index }}. {{ poi.name }}</span>
                <el-tag size="small" :type="getPoiTagType(poi.type)">{{ poi.type }}</el-tag>
              </div>
            </template>
            <div class="poi-card-content">
              <p><i class="el-icon-location"></i> 地址: {{ poi.address }}</p>
              <p><i class="el-icon-map-location"></i> 距离: {{ formatDistance(poi.distance) }}</p>
              <p v-if="poi.tel && poi.tel !== '无'"><i class="el-icon-phone"></i> 电话: {{ poi.tel }}</p>
            </div>
          </el-card>
        </div>
      </el-scrollbar>
    </div>
    <!-- 其他数据使用表格展示 -->
    <el-descriptions v-else :column="1" border>
      <el-descriptions-item
        v-for="(value, key) in attributes"
        :key="key"
        :label="getLabel(key as string)"
      >
        {{ value }}
      </el-descriptions-item>
    </el-descriptions>
  </el-dialog>

  <!-- 要素属性编辑对话框 -->
  <el-dialog v-model="featureFormVisible" :title="featureFormTitle" width="500px">
    <el-form label-width="120px">
      <!-- 点要素表单 -->
      <template v-if="currentInstruction?.layerType === 'POINT'">
        <el-form-item label="建筑名称" required>
          <el-input v-model="featureFormData.BuildingName" placeholder="请输入建筑名称"></el-input>
        </el-form-item>
        <el-form-item label="建筑类型">
          <el-input
            v-model="featureFormData.BuildingType"
            placeholder="请输入建筑类型"
            style="width: 100%"
          ></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input
            v-model="featureFormData.description"
            type="textarea"
            rows="3"
            placeholder="请输入描述信息"
          ></el-input>
        </el-form-item>
      </template>

      <!-- 线要素表单 -->
      <template v-if="currentInstruction?.layerType === 'LINE'">
        <el-form-item label="道路名称" required>
          <el-input v-model="featureFormData.RoadName" placeholder="请输入道路名称"></el-input>
        </el-form-item>
        <el-form-item label="道路类型">
          <el-input
            v-model="featureFormData.RoadType"
            placeholder="请输入道路类型"
            style="width: 100%"
          ></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input
            v-model="featureFormData.description"
            type="textarea"
            rows="3"
            placeholder="请输入描述信息"
          ></el-input>
        </el-form-item>
      </template>

      <!-- 面要素表单 -->
      <template v-if="currentInstruction?.layerType === 'POLYGON'">
        <el-form-item label="区域名称" required>
          <el-input v-model="featureFormData.AreaName" placeholder="请输入区域名称"></el-input>
        </el-form-item>
        <el-form-item label="服务类型">
          <el-input
            v-model="featureFormData.ServiceType"
            placeholder="请输入服务类型"
            style="width: 100%"
          ></el-input>
        </el-form-item>
        <el-form-item label="描述">
          <el-input
            v-model="featureFormData.description"
            type="textarea"
            rows="3"
            placeholder="请输入描述信息"
          ></el-input>
        </el-form-item>
      </template>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="featureFormVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmitFeatureForm()">确认</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.mapView {
  height: calc(100vh - 60px);
  width: 100%;
  margin: 0;
  padding: 0;
}

/* 周边查询结果样式 */
.poi-result-container {
  padding: 10px 0;
}

.poi-summary {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
  flex-wrap: wrap;
}

.poi-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.poi-card {
  margin-bottom: 5px;
  border-radius: 8px;
  transition: all 0.3s;
}

.poi-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.poi-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.poi-name {
  font-weight: bold;
  font-size: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 70%;
}

.poi-card-content {
  font-size: 14px;
  color: #606266;
  line-height: 1.6;
}

.poi-card-content p {
  margin: 5px 0;
  display: flex;
  align-items: center;
}

.poi-card-content i {
  margin-right: 5px;
}
</style>
